﻿/***********************************************************************************\
| Copyright (c) 2011, Bashar Al-Rawi                                                |
| All rights reserved.                                                              |
|                                                                                   |
| Redistribution and use in source and binary forms, with or without                |
| modification, are permitted provided that the following conditions are met:       |
|    * Redistributions of source code must retain the above copyright               |
|      notice, this list of conditions and the following disclaimer.                |
|    * Redistributions in binary form must reproduce the above copyright            |
|      notice, this list of conditions and the following disclaimer in the          |
|      documentation and/or other materials provided with the distribution.         |
|    * Neither the name of the <organization> nor the                               |
|      names of its contributors may be used to endorse or promote products         |
|      derived from this software without specific prior written permission.        |
|                                                                                   |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            |
| DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY                |
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND       |
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT        |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      |
\***********************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Diagnostics;

namespace Arabic.Utils
{
    public enum KeyboardLanguage
    {
        Arabic,
        English
    };

    public enum KeyCode
    {
        AR,
        EN,
        CONTROL
    }

    public enum FlowDirection
    {
        LeftToRight,
        RightToLeft
    }

    [XmlInclude(typeof(ArabicCharacter))]
    [XmlInclude(typeof(EnglishCharacter))]
    public abstract class Character
    {
        public const char BACKSPACE = '\u0008';
        public const int ENTER = 13;
        public int PlatformCode { get; set; }
        [XmlIgnore]
        public Character Prev { get; set; }
        [XmlIgnore]
        public Character Next { get; set; }
        public abstract string DisplayChar { get; }
        [XmlIgnore]
        public abstract string Char { get; }
        public string DefaultChar { get; set; }
        public KeyboardLanguage Language { get; set; }
        public KeyCode Lang { get; set; }
        public static void Initialize()
        {
            ArabicCharacter.Initialize();
            EnglishCharacter.Initialize();
        }

        public override string ToString()
        {
            return string.Format("Code={0}, Char={1}, DefaultChar={2}, DisplayChar={3}", PlatformCode, Char, DefaultChar, DisplayChar);
        }


        public static KeyboardLanguage CharLanguage(char ch)
        {
            if (ArabicCharacter.IsArabic(ch))
                return KeyboardLanguage.Arabic;
            else
                return KeyboardLanguage.English;
        }

        public static Character CreateCharacter(int platformCode)
        {
            string chStr = KeyCodeHelper.Translate(platformCode);
            char ch;
            if (!char.TryParse(chStr, out ch))
            {
                throw new ArgumentException("character cannot be parsed");
            }

            return CreateCharacter(ch);
        }

        public static Character CreateCharacter(char ch)
        {
            Character character = null;
            switch (CharLanguage(ch))
            {
                case KeyboardLanguage.Arabic:
                    character = new ArabicCharacter(ch, null, null);
                    break;
                case KeyboardLanguage.English:
                    character = new EnglishCharacter(ch, null, null);
                    break;
            }
            return character;
        }
    }
}
